home *** CD-ROM | disk | FTP | other *** search
/ Delphi 5 for Professionals / DELPHI5.iso / AddOns / Components / Orpheus v3.02 / SETUP.EXE / %MAINDIR% / Ovcsf.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-02-25  |  51.0 KB  |  1,917 lines

  1. {*********************************************************}
  2. {*                    OVCSF.PAS 3.00                     *}
  3. {*     Copyright 1995-99 (c) TurboPower Software Co      *}
  4. {*                 All rights reserved.                  *}
  5. {*********************************************************}
  6.  
  7. {$I OVC.INC}
  8.  
  9. {$B-} {Complete Boolean Evaluation}
  10. {$I+} {Input/Output-Checking}
  11. {$P+} {Open Parameters}
  12. {$T-} {Typed @ Operator}
  13. {$W-} {Windows Stack Frame}
  14. {$X+} {Extended Syntax}
  15.  
  16. {$IFNDEF Win32}
  17. {$G+} {286 Instructions}
  18. {$N+} {Numeric Coprocessor}
  19.  
  20. {$C MOVEABLE,DEMANDLOAD,DISCARDABLE}
  21. {$ENDIF}
  22.  
  23. unit OvcSF;
  24.   {-Simple field visual component}
  25.  
  26. interface
  27.  
  28. uses
  29.   {$IFDEF Win32} Windows, {$ELSE} WinTypes, WinProcs, {$ENDIF}
  30.   Classes, Controls, Forms, Graphics, Menus, Messages, SysUtils,
  31.   OvcBase, OvcColor, OvcCaret, OvcConst, OvcCmd,
  32.   OvcData, OvcEF, OvcExcpt, OvcIntl, OvcMisc, OvcStr;
  33.  
  34. type
  35.   {simple field type names}
  36.   TSimpleDataType    = (
  37.     sftString, sftChar, sftBoolean, sftYesNo,
  38.     sftLongInt, sftWord, sftInteger, sftByte, sftShortInt,
  39.     sftReal, sftExtended, sftDouble, sftSingle, sftComp);
  40.  
  41. type
  42.   TOvcCustomSimpleField = class(TOvcBaseEntryField)
  43.   {.Z+}
  44.   protected {private}
  45.     {property instance variables}
  46.     FSimpleDataType : TSimpleDataType;  {data type for this field}
  47.     FPictureMask    : AnsiChar;             {picture mask name}
  48.  
  49.     function sfGetDataType(Value : TSimpleDataType) : Byte;
  50.       {-return a Byte value representing the type of this field}
  51.     procedure sfResetFieldProperties(FT : TSimpleDataType);
  52.       {-reset field properties}
  53.     procedure sfSetDefaultRanges;
  54.       {-set default range values based on the field type}
  55.  
  56.   protected
  57.     procedure CreateWnd;
  58.       override;
  59.  
  60.     procedure efEdit(var Msg : TMessage; Cmd : Word);
  61.       override;
  62.       {-process the specified editing command}
  63.     function efGetDisplayString(Dest : PAnsiChar; Size : Word) : PAnsiChar;
  64.       override;
  65.       {-return the display string in Dest and a pointer as the result}
  66.     procedure efIncDecValue(Wrap : Boolean; Delta : Double);
  67.       override;
  68.       {-increment field by Delta}
  69.     function efTransfer(DataPtr : Pointer; TransferFlag : Word) : Word;
  70.       override;
  71.       {-transfer data to/from the entry fields}
  72.  
  73.     {virtual property methods}
  74.     procedure sfSetDataType(Value : TSimpleDataType);
  75.       virtual;
  76.       {-set the data type for this field}
  77.     procedure sfSetPictureMask(Value: AnsiChar);
  78.       virtual;
  79.       {-set the picture mask}
  80.  
  81.   public
  82.     procedure Assign(Source : TPersistent);
  83.       override;
  84.     constructor Create(AOwner: TComponent);
  85.       override;
  86.  
  87.     function efValidateField : Word;
  88.       override;
  89.       {-validate contents of field; result is error code or 0}
  90.   {.Z-}
  91.  
  92.     {public properties}
  93.     property DataType : TSimpleDataType
  94.       read FSimpleDataType
  95.       write sfSetDataType;
  96.  
  97.     property PictureMask : AnsiChar
  98.       read FPictureMask
  99.       write sfSetPictureMask;
  100.  
  101.   end;
  102.  
  103.   TOvcSimpleField = class(TOvcCustomSimpleField)
  104.   published
  105.     {inherited properties}
  106.     property DataType;       {needs to loaded before most other properties}
  107.     {$IFDEF VERSION4}
  108.     property Anchors;
  109.     property Constraints;
  110.     property DragKind;
  111.     {$ENDIF}
  112.     property AutoSize;
  113.     property BorderStyle;
  114.     property CaretIns;
  115.     property CaretOvr;
  116.     property Color;
  117.     property ControlCharColor;
  118.     property Controller;
  119.     property Ctl3D;
  120.     property DecimalPlaces;
  121.     property DragCursor;
  122.     property DragMode;
  123.     property EFColors;
  124.     property Enabled;
  125.     property Font;
  126.     property LabelInfo;
  127.     property MaxLength;
  128.     property Options;
  129.     property PadChar;
  130.     property ParentColor;
  131.     property ParentCtl3D;
  132.     property ParentFont;
  133.     property ParentShowHint;
  134.     property PasswordChar;
  135.     property PictureMask;
  136.     property PopupMenu;
  137.     property RangeHi stored False;
  138.     property RangeLo stored False;
  139.     property ShowHint;
  140.     property TabOrder;
  141.     property TabStop default True;
  142.     property Tag;
  143.     property TextMargin;
  144.     property Uninitialized;
  145.     property Visible;
  146.     property ZeroDisplay;
  147.     property ZeroDisplayValue;
  148.  
  149.     {inherited events}
  150.     property AfterEnter;
  151.     property AfterExit;
  152.     property OnChange;
  153.     property OnClick;
  154.     property OnDblClick;
  155.     property OnDragDrop;
  156.     property OnDragOver;
  157.     property OnEndDrag;
  158.     property OnEnter;
  159.     property OnError;
  160.     property OnExit;
  161.     property OnKeyDown;
  162.     property OnKeyPress;
  163.     property OnKeyUp;
  164.     property OnMouseDown;
  165.     property OnMouseMove;
  166.     property OnMouseUp;
  167.     {$IFDEF Win32}
  168.     property OnStartDrag;
  169.     property OnMouseWheel;
  170.     {$ENDIF}
  171.     property OnUserCommand;
  172.     property OnUserValidation;
  173.   end;
  174.  
  175.  
  176. implementation
  177.  
  178.  
  179. {*** TOvcCustomSimpleField ***}
  180.  
  181. procedure TOvcCustomSimpleField.Assign(Source : TPersistent);
  182. var
  183.   SF : TOvcCustomSimpleField absolute Source;
  184. begin
  185.   if (Source <> nil) and (Source is TOvcCustomSimpleField) then begin
  186.     DataType             := SF.DataType;
  187.     AutoSize             := SF.AutoSize;
  188.     BorderStyle          := SF.BorderStyle;
  189.     Color                := SF.Color;
  190.     ControlCharColor     := SF.ControlCharColor;
  191.     DecimalPlaces        := SF.DecimalPlaces;
  192.     EFColors.Error.Assign(SF.EFColors.Error);
  193.     EFColors.Highlight.Assign(SF.EFColors.Highlight);
  194.     MaxLength            := SF.MaxLength;
  195.     Options              := SF.Options;
  196.     PadChar              := SF.PadChar;
  197.     PasswordChar         := SF.PasswordChar;
  198.     PictureMask          := SF.PictureMask;
  199.     RangeHi              := SF.RangeHi;
  200.     RangeLo              := SF.RangeLo;
  201.     TextMargin           := SF.TextMargin;
  202.     Uninitialized        := SF.Uninitialized;
  203.     ZeroDisplay          := SF.ZeroDisplay;
  204.     ZeroDisplayValue     := SF.ZeroDisplayValue;
  205.   end else
  206.     inherited Assign(Source);
  207. end;
  208.  
  209. constructor TOvcCustomSimpleField.Create(AOwner: TComponent);
  210. begin
  211.   inherited Create(AOwner);
  212.  
  213.   FSimpleDataType := sftString;
  214.   FPictureMask    := pmAnyChar;
  215.  
  216.   efFieldClass    := fcSimple;
  217.   efDataType      := sfGetDataType(FSimpleDataType);
  218.   efPicture[0]    := pmAnyChar;
  219.   efPicture[1]    := #0;
  220. end;
  221.  
  222. procedure TOvcCustomSimpleField.CreateWnd;
  223. var
  224.   P : array[0..MaxEditLen+1] of Byte;
  225. begin
  226.   {save field data}
  227.   if efSaveData then
  228.     efTransfer(@P, otf_GetData);
  229.  
  230.   inherited CreateWnd;
  231.  
  232.   sfSetDefaultRanges;
  233.   efSetInitialValue;
  234.  
  235.   {if we saved the field data, restore it}
  236.   if efSaveData then
  237.     efTransfer(@P, otf_SetData);
  238.  
  239.   {set save data flag}
  240.   efSaveData := True;
  241. end;
  242.  
  243. procedure TOvcCustomSimpleField.efEdit(var Msg : TMessage; Cmd : Word);
  244.   {-process the specified editing command}
  245.  
  246.   procedure EditSimple(var Msg : TMessage; Cmd : Word);
  247.     {-process the specified editing command for String and PChar fields}
  248.   label
  249.     ExitPoint;
  250.   var
  251.     SaveHPos    : Word;
  252.     DelEnd      : Word;
  253.     Len         : Word;
  254.     Ch          : AnsiChar;
  255.     PrevCh      : AnsiChar;
  256.     MF          : ShortInt;
  257.     HaveSel     : Boolean;
  258.     SelExtended : Boolean;
  259.  
  260.     function CharIsOK : Boolean;
  261.       {-return true if Ch can be added to the string}
  262.     var
  263.       PrevCh : AnsiChar;
  264.     begin
  265.       if efIsNumericType then
  266.         if Ch = IntlSupport.DecimalChar then
  267.           Ch := pmDecimalPt
  268.         else if Ch = pmDecimalPt then
  269.           Ch := #0;
  270.       if (Ch < ' ') and not (sefLiteral in sefOptions) then begin
  271.         CharIsOK := False;
  272.         Exit;
  273.       end;
  274.       if efHPos = 0 then
  275.         PrevCh := ' '
  276.       else
  277.         PrevCh := efEditSt[efHPos-1];
  278.       CharIsOK := efCharOK(efPicture[0], Ch, PrevCh, True);
  279.       if efIsNumericType and (Ch = pmDecimalPt) then
  280.         Ch := IntlSupport.DecimalChar;
  281.     end;
  282.  
  283.     function CheckAutoAdvance(SP : Integer) : Boolean;
  284.       {-see if we need to auto-advance to next/previous field}
  285.     begin
  286.       CheckAutoAdvance := False;
  287.       if (SP < 0) and
  288.         (efoAutoAdvanceLeftRight in Controller.EntryOptions) then begin
  289.         efMoveFocusToPrevField;
  290.         CheckAutoAdvance := True;
  291.       end else if (SP >= MaxLength) then
  292.         if (Cmd = ccChar) and
  293.            (efoAutoAdvanceChar in Controller.EntryOptions) then begin
  294.           efMoveFocusToNextField;
  295.           CheckAutoAdvance := True;
  296.         end else if (Cmd <> ccChar) and
  297.                     (efoAutoAdvanceLeftRight in Controller.EntryOptions) then begin
  298.           efMoveFocusToNextField;
  299.           CheckAutoAdvance := True;
  300.         end;
  301.     end;
  302.  
  303.     procedure FixSelValues;
  304.     var
  305.       I : Integer;
  306.     begin
  307.       if efSelStart > efSelEnd then begin
  308.         I := efSelStart;
  309.         efSelStart := efSelEnd;
  310.         efSelEnd := I;
  311.       end;
  312.     end;
  313.  
  314.     procedure UpdateSel;
  315.     begin
  316.       if efSelStart = SaveHPos then
  317.         efSelStart := efHPos
  318.       else
  319.         efSelEnd := efHPos;
  320.       FixSelValues;
  321.     end;
  322.  
  323.     procedure WordLeftPrim;
  324.     begin
  325.       Dec(efHPos);
  326.       while (efHPos >= 0) and ((efHPos >= Len) or (efEditSt[efHPos] = ' ')) do
  327.         Dec(efHPos);
  328.       while (efHPos >= 0) and (efEditSt[efHPos] <> ' ') do
  329.         Dec(efHPos);
  330.       Inc(efHPos);
  331.     end;
  332.  
  333.     procedure WordRightPrim;
  334.     begin
  335.       if efEditSt[efHPos] <> ' ' then
  336.         Inc(efHPos);
  337.       while (efHPos < Len) and (efEditSt[efHPos] <> ' ') do
  338.         Inc(efHPos);
  339.       while (efHPos < Len) and (efEditSt[efHPos] = ' ') do
  340.         Inc(efHPos);
  341.     end;
  342.  
  343.     procedure DeleteSel;
  344.     begin
  345.       StrStDeletePrim(efEditSt, efSelStart, efSelEnd-efSelStart);
  346.       Len := StrLen(efEditSt);
  347.       efHPos := efSelStart;
  348.       efSelEnd := efHPos;
  349.       MF := 10;
  350.     end;
  351.  
  352.     procedure PastePrim(P : PAnsiChar);
  353.     var
  354.       Ch    : AnsiChar;
  355.       IsNum : Boolean;
  356.     begin
  357.       if HaveSel then
  358.         DeleteSel;
  359.       IsNum := efIsNumericType;
  360.       while P^ <> #0 do begin
  361.         Ch := P^;
  362.         if IsNum then
  363.           if Ch = IntlSupport.DecimalChar then
  364.             Ch := pmDecimalPt
  365.           else if (Ch = pmDecimalPt) or (Ch = ' ') then
  366.             Ch := #0;
  367.         if efCharOK(efPicture[0], Ch, #255, True) then begin
  368.           if (Len = MaxLength) and (efHPos < Len) and
  369.              (efoInsertPushes in Controller.EntryOptions) then begin
  370.             Dec(Len);
  371.             efEditSt[Len] := #0;
  372.           end;
  373.           if (Len < MaxLength) then begin
  374.             if efIsNumericType and (Ch = pmDecimalPt) then
  375.               Ch := IntlSupport.DecimalChar;
  376.             StrChInsertPrim(efEditSt, Ch, efHPos);
  377.             Inc(efHPos);
  378.             Inc(Len);
  379.           end;
  380.           MF := 10;
  381.         end;
  382.         Inc(P);
  383.       end;
  384.     end;
  385.  
  386.   begin
  387.     HaveSel := efSelStart <> efSelEnd;
  388.     MF := Ord(HaveSel);
  389.     SaveHPos := efHPos;
  390.     SelExtended := False;
  391.  
  392.     case Cmd of
  393.       ccAccept   : {};
  394.       ccCtrlChar : Include(sefOptions, sefLiteral);
  395.     else
  396.       if Cmd <> ccChar then
  397.         Exclude(sefOptions, sefLiteral);
  398.     end;
  399.  
  400.     Len := StrLen(efEditSt);
  401.     Exclude(sefOptions, sefCharOK);
  402.  
  403.     case Cmd of
  404.       ccChar :
  405.         begin
  406.           Ch := AnsiChar(Lo(Msg.wParam));
  407.           if (sefAcceptChar in sefOptions) and CharIsOk then begin
  408.             Exclude(sefOptions, sefAcceptChar);
  409.             Exclude(sefOptions, sefLiteral);
  410.             if HaveSel then begin
  411.               DeleteSel;
  412.               if efHPos = 0 then
  413.                 PrevCh := ' '
  414.               else
  415.                 PrevCh := efEditSt[efHPos-1];
  416.               efCharOK(efPicture[0], Ch, PrevCh, True);
  417.             end;
  418.             if (sefInsert in sefOptions) then begin
  419.               if (Len = MaxLength) and (efHPos < Len) and
  420.                  (efoInsertPushes in Controller.EntryOptions) then begin
  421.                 Dec(Len);
  422.                 efEditSt[Len] := #0;
  423.               end;
  424.               if (Len < MaxLength) then begin
  425.                 StrChInsertPrim(efEditSt, Ch, efHPos);
  426.                 Inc(efHPos);
  427.                 CheckAutoAdvance(efHPos);
  428.               end else if not CheckAutoAdvance(efHPos) then
  429.                 efConditionalBeep;
  430.             end else if (efHPos+1) <= MaxLength then begin
  431.               efEditSt[efHPos] := Ch;
  432.               if efHPos >= Len then
  433.                 efEditSt[efHPos+1] := #0;
  434.               Inc(efHPos);
  435.               CheckAutoAdvance(efHPos);
  436.             end else begin
  437.               if not CheckAutoAdvance(efHPos) then
  438.                 efConditionalBeep;
  439.               Dec(MF, 10);
  440.             end;
  441.             Inc(MF, 10);
  442.           end else begin
  443.             Exclude(sefOptions, sefLiteral);
  444.             if sefAcceptChar in sefOptions then
  445.               efConditionalBeep
  446.             else
  447.               goto ExitPoint;
  448.           end;
  449.         end;
  450.       ccMouse :
  451.         if Len > 0 then begin
  452.           efHPos := efGetMousePos(SmallInt(Msg.lParamLo));
  453.           {drag highlight initially if shift key is being pressed}
  454.           if (GetKeyState(vk_Shift) < 0) then begin
  455.             SelExtended := True;
  456.             if HaveSel then begin
  457.               if efHPos > efSelStart then
  458.                 efSelEnd := efHPos
  459.               else
  460.                 efSelStart := efHPos;
  461.             end else begin
  462.               efSelStart := SaveHPos;
  463.               efSelEnd := efHPos;
  464.             end;
  465.             FixSelValues;
  466.           end else begin
  467.             SetSelection(efHPos, efHPos);
  468.             efPositionCaret(False);
  469.           end;
  470.         end;
  471.       ccMouseMove :
  472.         if Len > 0 then begin
  473.           efHPos := efGetMousePos(SmallInt(Msg.lParamLo));
  474.           UpdateSel;
  475.         end;
  476.       ccDblClk :
  477.         if Len > 0 then begin
  478.           efHPos := efGetMousePos(SmallInt(Msg.lParamLo));
  479.           WordLeftPrim;
  480.           SaveHPos := efHPos;
  481.           efSelStart := SaveHPos;
  482.           efSelEnd := SaveHPos;
  483.           WordRightPrim;
  484.           UpdateSel;
  485.         end;
  486.       ccLeft :
  487.         if efHPos > 0 then
  488.           Dec(efHPos)
  489.         else
  490.           CheckAutoAdvance(-1);
  491.       ccRight :
  492.         if efHPos < Len then
  493.           Inc(efHPos)
  494.         else
  495.           CheckAutoAdvance(MaxLength);
  496.       ccUp :
  497.         if (efoAutoAdvanceUpDown in Controller.EntryOptions) then
  498.           efMoveFocusToPrevField
  499.         else if (efoArrowIncDec in Options) and not (efoReadOnly in Options) then
  500.           IncreaseValue(True, 1)
  501.         else if efHPos > 0 then
  502.           Dec(efHPos)
  503.         else
  504.           CheckAutoAdvance(-1);
  505.       ccDown :
  506.         if (efoAutoAdvanceUpDown in Controller.EntryOptions) then
  507.           efMoveFocusToNextField
  508.         else if (efoArrowIncDec in Options) and not (efoReadOnly in Options) then
  509.           DecreaseValue(True, 1)
  510.         else if efHPos < Len then
  511.           Inc(efHPos)
  512.         else
  513.           CheckAutoAdvance(MaxLength);
  514.       ccWordLeft :
  515.         if efHPos > 0 then
  516.           WordLeftPrim
  517.         else
  518.           CheckAutoAdvance(-1);
  519.       ccWordRight :
  520.         if efHPos < Len then
  521.           WordRightPrim
  522.         else
  523.           CheckAutoAdvance(MaxLength);
  524.       ccHome :
  525.         efHPos := 0;
  526.       ccEnd :
  527.         efHPos := Len;
  528.       ccExtendLeft :
  529.         if efHPos > 0 then begin
  530.           Dec(efHPos);
  531.           UpdateSel;
  532.         end else
  533.           MF := -1;
  534.       ccExtendRight :
  535.         if efHPos < Len then begin
  536.           Inc(efHPos);
  537.           UpdateSel;
  538.         end else
  539.           MF := -1;
  540.       ccExtendHome :
  541.         begin
  542.           efHPos := 0;
  543.           UpdateSel;
  544.         end;
  545.       ccExtendEnd :
  546.         begin
  547.           efHPos := Len;
  548.           UpdateSel;
  549.         end;
  550.       ccExtWordLeft :
  551.         if efHPos > 0 then begin
  552.           WordLeftPrim;
  553.           UpdateSel;
  554.         end else
  555.           MF := -1;
  556.       ccExtWordRight :
  557.         if efHPos < Len then begin
  558.           WordRightPrim;
  559.           UpdateSel;
  560.         end else
  561.           MF := -1;
  562.       ccCut :
  563.         if HaveSel then
  564.           DeleteSel;
  565.       ccCopy : efCopyPrim;    {3.00}
  566.       ccPaste :
  567.         PastePrim(PAnsiChar(Msg.lParam));
  568.       ccBack :
  569.         if HaveSel then
  570.           DeleteSel
  571.         else if efHPos > 0 then begin
  572.           Dec(efHPos);
  573.           StrStDeletePrim(efEditSt, efHPos, 1);
  574.           MF := 10;
  575.         end;
  576.       ccDel :
  577.         if HaveSel then
  578.           DeleteSel
  579.         else if efHPos < Len then begin
  580.           StrStDeletePrim(efEditSt, efHPos, 1);
  581.           MF := 10;
  582.         end;
  583.       ccDelWord :
  584.         if HaveSel then
  585.           DeleteSel
  586.         else if efHPos < Len then begin
  587.           {start deleting at the caret}
  588.           DelEnd := efHPos;
  589.  
  590.           {delete all of the current word, if any}
  591.           if efEditSt[efHPos] <> ' ' then
  592.             while (efEditSt[DelEnd] <> ' ') and (DelEnd < Len) do
  593.               Inc(DelEnd);
  594.  
  595.           {delete any spaces prior to the next word, if any}
  596.           while (efEditSt[DelEnd] = ' ') and (DelEnd < Len) do
  597.             Inc(DelEnd);
  598.  
  599.           StrStDeletePrim(efEditSt, efHPos, DelEnd-efHPos);
  600.           MF := 10;
  601.         end;
  602.       ccDelLine :
  603.         if Len > 0 then begin
  604.           efEditSt[0] := #0;
  605.           efHPos := 0;
  606.           MF := 10;
  607.         end;
  608.       ccDelEol :
  609.         if efHPos < Len then begin
  610.           efEditSt[efHPos] := #0;
  611.           MF := 10;
  612.         end;
  613.       ccDelBol :
  614.         if Len > 0 then begin
  615.           StrStDeletePrim(efEditSt, 0, efHPos);
  616.           efHPos := 0;
  617.           MF := 10;
  618.         end;
  619.       ccIns :
  620.         begin
  621.           if sefInsert in sefOptions then
  622.             Exclude(sefOptions, sefInsert)
  623.           else
  624.             Include(sefOptions, sefInsert);
  625.           efCaret.InsertMode := (sefInsert in sefOptions);
  626.         end;
  627.       ccRestore : Restore;
  628.       ccAccept :
  629.         begin
  630.           Include(sefOptions, sefCharOK);
  631.           Include(sefOptions, sefAcceptChar);
  632.           Exit;
  633.         end;
  634.       ccDec :
  635.         DecreaseValue(True, 1);
  636.       ccInc :
  637.         IncreaseValue(True, 1);
  638.       ccCtrlChar, ccSuppress, ccPartial :
  639.         goto ExitPoint;
  640.     else
  641.       Include(sefOptions, sefCharOK);
  642.       goto ExitPoint;
  643.     end;
  644.     Exclude(sefOptions, sefAcceptChar);
  645.  
  646.     case Cmd of
  647.       ccRestore, ccMouseMove, ccDblClk,
  648.       ccExtendLeft, ccExtendRight,
  649.       ccExtendHome, ccExtendEnd,
  650.       ccExtWordLeft, ccExtWordRight :
  651.         Inc(MF);
  652.       ccMouse :
  653.         if SelExtended then
  654.           Inc(MF);
  655.     else
  656.       efSelStart := efHPos;
  657.       efSelEnd := efHPos;
  658.     end;
  659.  
  660.   ExitPoint:
  661.     if efPositionCaret(True) then
  662.       Inc(MF);
  663.     if MF >= 10 then
  664.       efFieldModified;
  665.     if MF > 0 then
  666.       Invalidate;
  667.   end;
  668.  
  669.   procedure EditChar(var Msg : TMessage; Cmd : Word);
  670.     {-process the specified editing command for Char fields}
  671.   label
  672.     ExitPoint;
  673.   var
  674.     MF : Byte;
  675.     Ch : AnsiChar;
  676.  
  677.     function CharIsOK : Boolean;
  678.       {-return true if Ch can be added to the string}
  679.     begin
  680.       if (Ch < ' ') and not (sefLiteral in sefOptions) then
  681.         CharIsOK := False
  682.       else
  683.         CharIsOK := efCharOK(efPicture[0], Ch, ' ', True);
  684.     end;
  685.  
  686.     function CheckAutoAdvance(SP : Integer) : Boolean;
  687.       {-see if we need to auto-advance to next/previous field}
  688.     begin
  689.       CheckAutoAdvance := False;
  690.       if (SP < 0) and
  691.          (efoAutoAdvanceLeftRight in Controller.EntryOptions) then begin
  692.         efMoveFocusToPrevField;
  693.         Result := True;
  694.       end else if (SP > 0) then
  695.         if (Cmd = ccChar) and
  696.            (efoAutoAdvanceChar in Controller.EntryOptions) then begin
  697.           efMoveFocusToNextField;
  698.           Result := True;
  699.         end else if (Cmd <> ccChar) and
  700.                     (efoAutoAdvanceLeftRight in Controller.EntryOptions) then begin
  701.           efMoveFocusToNextField;
  702.           Result := True;
  703.         end;
  704.     end;
  705.  
  706.     procedure PastePrim(P : PAnsiChar);
  707.     begin
  708.       while P^ <> #0 do begin
  709.         Ch := P^;
  710.         if efCharOK(efPicture[0], Ch, #255, True) then begin
  711.           efEditSt[0] := Ch;
  712.           MF := 10;
  713.           Exit;
  714.         end;
  715.         Inc(P);
  716.       end;
  717.     end;
  718.  
  719.   begin
  720.     MF := Ord(efSelStart <> efSelEnd);
  721.     case Cmd of
  722.       ccAccept : ;
  723.       ccCtrlChar :
  724.         Include(sefOptions, sefLiteral);
  725.       else
  726.         efHPos := 0;
  727.         if Cmd <> ccChar then
  728.           Exclude(sefOptions, sefLiteral);
  729.     end;
  730.  
  731.     Exclude(sefOptions, sefCharOK);
  732.     case Cmd of
  733.       ccChar :
  734.         begin
  735.           Ch := AnsiChar(Lo(Msg.wParam));
  736.           if sefAcceptChar in sefOptions then
  737.             if CharIsOk then begin
  738.               efEditSt[0] := Ch;
  739.               efEditSt[1] := #0;
  740.               CheckAutoAdvance(1);
  741.               MF := 10;
  742.             end else
  743.               efConditionalBeep;
  744.             {end;}
  745.           sefOptions := sefOptions - [sefAcceptChar, sefLiteral];
  746.         end;
  747.       ccLeft, ccWordLeft :
  748.         CheckAutoAdvance(-1);
  749.       ccRight, ccWordRight :
  750.         CheckAutoAdvance(MaxLength);
  751.       ccUp :
  752.         if (efoAutoAdvanceUpDown in Controller.EntryOptions) then
  753.           efMoveFocusToPrevField
  754.         else
  755.           CheckAutoAdvance(-1);
  756.       ccDown :
  757.         if (efoAutoAdvanceUpDown in Controller.EntryOptions) then
  758.           efMoveFocusToNextField
  759.         else
  760.           CheckAutoAdvance(MaxLength);
  761.       ccRestore :
  762.         Restore;
  763.       ccExtendRight, ccExtendEnd, ccExtWordRight :
  764.         efSelEnd := 1;
  765.       ccMouseMove :
  766.         if efGetMousePos(SmallInt(Msg.lParamLo)) > 0 then
  767.           efSelEnd := 1
  768.         else
  769.           efSelEnd := 0;
  770.       ccDblClk :
  771.         efSelEnd := 1;
  772.       ccCopy : efCopyPrim;    {3.00}
  773.       ccPaste :
  774.         PastePrim(PAnsiChar(Msg.lParam));
  775.       ccAccept :
  776.         begin
  777.           sefOptions := sefOptions + [sefCharOK, sefAcceptChar];
  778.           Exit;
  779.         end;
  780.       ccMouse, ccExtendLeft, ccExtendHome, ccExtWordLeft : ;
  781.       ccDec :
  782.         DecreaseValue(True, 1);
  783.       ccInc :
  784.         IncreaseValue(True, 1);
  785.       ccCtrlChar, ccSuppress, ccPartial :
  786.         goto ExitPoint;
  787.     else
  788.       Include(sefOptions, sefCharOK);
  789.       goto ExitPoint;
  790.     end;
  791.     Exclude(sefOptions, sefAcceptChar);
  792.  
  793.     case Cmd of
  794.       ccRestore, ccMouseMove, ccDblClk, ccExtendRight,
  795.       ccExtendEnd, ccExtWordRight :
  796.         Inc(MF);
  797.     else
  798.       efSelStart := 0;
  799.       efSelEnd := 0;
  800.     end;
  801.  
  802.   ExitPoint:
  803.     if efPositionCaret(True) then
  804.       Inc(MF);
  805.     if MF >= 10 then
  806.       efFieldModified;
  807.     if MF > 0 then
  808.       Invalidate;
  809.   end;
  810.  
  811. begin  {edit}
  812.   case FSimpleDataType of
  813.     sftString,
  814.     sftLongInt, sftWord, sftInteger, sftByte, sftShortInt,
  815.     sftReal, sftExtended, sftDouble, sftSingle, sftComp :
  816.       EditSimple(Msg, Cmd);
  817.     sftChar, sftBoolean, sftYesNo :
  818.       EditChar(Msg, Cmd);
  819.   end;
  820. end;
  821.  
  822. function TOvcCustomSimpleField.efGetDisplayString(Dest : PAnsiChar; Size : Word) : PAnsiChar;
  823.   {-return the display string in Dest and a pointer as the result}
  824. var
  825.   Len   : Word;
  826. begin
  827.   Result := inherited efGetDisplayString(Dest, Size);
  828.  
  829.   Len := StrLen(Dest);
  830.   if Len = 0 then
  831.     Exit;
  832.  
  833.   if Uninitialized and not (sefHaveFocus in sefOptions) then begin
  834.     FillChar(Dest[0], Len, ' ');
  835.     Exit;
  836.   end;
  837.  
  838.   if (efoPasswordMode in Options) then
  839.     FillChar(Dest[0], Len, PasswordChar);
  840.  
  841.   if PadChar <> ' ' then begin
  842.     FillChar(Dest[Len], MaxLength-Len, PadChar);
  843.     Dest[MaxLength] := #0;
  844.   end;
  845. end;
  846.  
  847. procedure TOvcCustomSimpleField.efIncDecValue(Wrap : Boolean; Delta : Double);
  848.   {-increment field by Delta}
  849. var
  850.   S : TEditString;
  851.  
  852.   procedure IncDecValueChar;
  853.     {-increment Char field by Delta}
  854.   var
  855.     C, CC, CL, CH, MC : AnsiChar;
  856.     OK : Boolean;
  857.   begin
  858.     {get valid range}
  859.     CL := efRangeLo.rtChar;
  860.     CH := efRangeHi.rtChar;
  861.     if CL = CH then begin
  862.       CL := #1;
  863.       CH := #255;
  864.     end;
  865.  
  866.     {get current character}
  867.     C := efEditSt[0];
  868.  
  869.     {get mask character}
  870.     MC := efPicture[0];
  871.  
  872.     {exit if we're at the range limit and not allowed to wrap}
  873.     if (Delta < 0) and (C = CL) then begin
  874.       if not Wrap then
  875.         Exit;
  876.     end else if (Delta > 0) and (C = CH) then
  877.       if not Wrap then
  878.         Exit;
  879.  
  880.     {find the next/prev allowable character}
  881.     OK := False;
  882.     repeat
  883.       repeat
  884.         if Delta = 1 then
  885.           Inc(C)
  886.         else
  887.           Dec(C);
  888.         CC := C;
  889.         efFixCase(MC, CC, ' ');
  890.       until efCharOK(MC, C, ' ', False) and (C = CC);
  891.  
  892.       {check result to see if it's in valid range}
  893.       if (C >= CL) and (C <= CH) then
  894.         OK := True
  895.       else if Wrap then
  896.         OK := False
  897.       else
  898.         Exit;
  899.     until OK;
  900.  
  901.     efTransfer(@C, otf_SetData);
  902.     efPerformRepaint(True);
  903.   end;
  904.  
  905.   procedure IncDecValueBoolean;
  906.   var
  907.     Ch : AnsiChar;
  908.     B  : Boolean;
  909.   begin
  910.     Ch := UpCaseChar(efEditSt[0]);
  911.     if Ch = IntlSupport.TrueChar then
  912.       Ch := IntlSupport.FalseChar
  913.     else
  914.       Ch := IntlSupport.TrueChar;
  915.     B := Ch = IntlSupport.TrueChar;
  916.  
  917.     efTransfer(@B, otf_SetData);
  918.     efPerformRepaint(True);
  919.   end;
  920.  
  921.   procedure IncDecValueYesNo;
  922.   var
  923.     Ch : AnsiChar;
  924.     B  : Boolean;
  925.   begin
  926.     Ch := UpCaseChar(efEditSt[0]);
  927.     if Ch = IntlSupport.YesChar then
  928.       Ch := IntlSupport.NoChar
  929.     else
  930.       Ch := IntlSupport.YesChar;
  931.     B := Ch = IntlSupport.YesChar;
  932.  
  933.     efTransfer(@B, otf_SetData);
  934.     efPerformRepaint(True);
  935.   end;
  936.  
  937.   procedure IncDecValueLongInt;
  938.   var
  939.     L : LongInt;
  940.   begin
  941.     if efStr2Long(efEditSt, L) then begin
  942.       if (Delta < 0) and (L <= efRangeLo.rtLong) then
  943.         if Wrap then
  944.           L := efRangeHi.rtLong
  945.         else Exit
  946.       else if (Delta > 0) and (L >= efRangeHi.rtLong) then
  947.         if Wrap then
  948.           L := efRangeLo.rtLong
  949.         else Exit
  950.       else
  951.         Inc(L, Trunc(Delta));
  952.  
  953.       {insure valid value}
  954.       if L < efRangeLo.rtLong then
  955.         L := efRangeLo.rtLong;
  956.       if L > efRangeHi.rtLong then
  957.         L := efRangeHi.rtLong;
  958.  
  959.       efTransfer(@L, otf_SetData);
  960.       efPerformRepaint(True);
  961.     end;
  962.   end;
  963.  
  964.   procedure IncDecValueReal;
  965.   var
  966.     Re   : Real;
  967.     Code : Integer;
  968.   begin
  969.     {convert efEditSt to a real}
  970.     StrLCopy(S, efEditSt, 80);
  971.     FixRealPrim(S, IntlSupport.DecimalChar);
  972.     Val(S, Re, Code);
  973.     if Code = 0 then begin
  974.       if (Delta < 0) and (Re <= efRangeLo.rtReal) then
  975.         if Wrap then
  976.           Re := efRangeHi.rtReal
  977.         else Exit
  978.       else if (Delta > 0) and (Re >= efRangeHi.rtReal) then
  979.         if Wrap then
  980.           Re := efRangeLo.rtReal
  981.         else Exit
  982.       else
  983.         Re := Re + Delta;
  984.  
  985.       {insure valid value}
  986.       if Re < efRangeLo.rtReal then
  987.         Re := efRangeLo.rtReal;
  988.       if Re > efRangeHi.rtReal then
  989.         Re := efRangeHi.rtReal;
  990.  
  991.       efTransfer(@Re, otf_SetData);
  992.       efPerformRepaint(True);
  993.     end;
  994.   end;
  995.  
  996.   procedure IncDecValueExtended;
  997.   var
  998.     Ex   : Extended;
  999.     Code : Integer;
  1000.   begin
  1001.     {convert efEditSt to an real}
  1002.     StrLCopy(S, efEditSt, 80);
  1003.     FixRealPrim(S, IntlSupport.DecimalChar);
  1004.     Val(S, Ex, Code);
  1005.     if Code = 0 then begin
  1006.       if (Delta < 0) and (Ex <= efRangeLo.rtExt) then
  1007.         if Wrap then
  1008.           Ex := efRangeHi.rtExt
  1009.         else Exit
  1010.       else if (Delta > 0) and (Ex >= efRangeHi.rtExt) then
  1011.         if Wrap then
  1012.           Ex := efRangeLo.rtExt
  1013.         else Exit
  1014.       else
  1015.         Ex := Ex + Delta;
  1016.  
  1017.       {insure valid value}
  1018.       if Ex < efRangeLo.rtExt then
  1019.         Ex := efRangeLo.rtExt;
  1020.       if Ex > efRangeHi.rtExt then
  1021.         Ex := efRangeHi.rtExt;
  1022.  
  1023.       efTransfer(@Ex, otf_SetData);
  1024.       efPerformRepaint(True);
  1025.     end;
  1026.   end;
  1027.  
  1028.   procedure IncDecValueDouble;
  1029.   var
  1030.     Db   : Double;
  1031.     Code : Integer;
  1032.   begin
  1033.     {convert efEditSt to an real}
  1034.     StrLCopy(S, efEditSt, 80);
  1035.     FixRealPrim(S, IntlSupport.DecimalChar);
  1036.     Val(S, Db, Code);
  1037.     if Code = 0 then begin
  1038.       if (Delta < 0) and (Db <= efRangeLo.rtExt) then
  1039.         if Wrap then
  1040.           Db := efRangeHi.rtExt
  1041.         else Exit
  1042.       else if (Delta > 0) and (Db >= efRangeHi.rtExt) then
  1043.         if Wrap then
  1044.           Db := efRangeLo.rtExt
  1045.         else Exit
  1046.       else
  1047.         Db := Db + Delta;
  1048.  
  1049.       {insure valid value}
  1050.       if Db < efRangeLo.rtExt then
  1051.         Db := efRangeLo.rtExt;
  1052.       if Db > efRangeHi.rtExt then
  1053.         Db := efRangeHi.rtExt;
  1054.  
  1055.       efTransfer(@Db, otf_SetData);
  1056.       efPerformRepaint(True);
  1057.     end;
  1058.   end;
  1059.  
  1060.   procedure IncDecValueSingle;
  1061.   var
  1062.     Si   : Single;
  1063.     Code : Integer;
  1064.   begin
  1065.     {convert efEditSt to an real}
  1066.     StrLCopy(S, efEditSt, 80);
  1067.     FixRealPrim(S, IntlSupport.DecimalChar);
  1068.     Val(S, Si, Code);
  1069.     if Code = 0 then begin
  1070.       if (Delta < 0) and (Si <= efRangeLo.rtExt) then
  1071.         if Wrap then
  1072.           Si := efRangeHi.rtExt
  1073.         else Exit
  1074.       else if (Delta > 0) and (Si >= efRangeHi.rtExt) then
  1075.         if Wrap then
  1076.           Si := efRangeLo.rtExt
  1077.         else Exit
  1078.       else
  1079.         Si := Si + Delta;
  1080.  
  1081.       {insure valid value}
  1082.       if Si < efRangeLo.rtExt then
  1083.         Si := efRangeLo.rtExt;
  1084.       if Si > efRangeHi.rtExt then
  1085.         Si := efRangeHi.rtExt;
  1086.  
  1087.       efTransfer(@Si, otf_SetData);
  1088.       efPerformRepaint(True);
  1089.     end;
  1090.   end;
  1091.  
  1092.   procedure IncDecValueComp;
  1093.   var
  1094.     Co   : Comp;
  1095.     Code : Integer;
  1096.   begin
  1097.     {convert efEditSt to an real}
  1098.     StrLCopy(S, efEditSt, 80);
  1099.     FixRealPrim(S, IntlSupport.DecimalChar);
  1100.     Val(S, Co, Code);
  1101.     if Code = 0 then begin
  1102.       if (Delta < 0) and (Co <= efRangeLo.rtExt) then
  1103.         if Wrap then
  1104.           Co := efRangeHi.rtExt
  1105.         else Exit
  1106.       else if (Delta > 0) and (Co >= efRangeHi.rtExt) then
  1107.         if Wrap then
  1108.           Co := efRangeLo.rtExt
  1109.         else Exit
  1110.       else
  1111.         Co := Co + Delta;
  1112.  
  1113.       {insure valid value}
  1114.       if Co < efRangeLo.rtExt then
  1115.         Co := efRangeLo.rtExt;
  1116.       if Co > efRangeHi.rtExt then
  1117.         Co := efRangeHi.rtExt;
  1118.  
  1119.       efTransfer(@Co, otf_SetData);
  1120.       efPerformRepaint(True);
  1121.     end;
  1122.   end;
  1123.  
  1124. begin
  1125.   if not (sefHaveFocus in sefOptions) then
  1126.     Exit;
  1127.   case FSimpleDataType of
  1128.     sftString   : {not supported for this field type};
  1129.     sftChar     : IncDecValueChar;
  1130.     sftBoolean  : IncDecValueBoolean;
  1131.     sftYesNo    : IncDecValueYesNo;
  1132.     sftLongInt,
  1133.     sftWord,
  1134.     sftInteger,
  1135.     sftByte,
  1136.     sftShortInt : IncDecValueLongInt;
  1137.     sftReal     : IncDecValueReal;
  1138.     sftExtended : IncDecValueExtended;
  1139.     sftDouble   : IncDecValueDouble;
  1140.     sftSingle   : IncDecValueSingle;
  1141.     sftComp     : IncDecValueComp;
  1142.   else
  1143.     raise EOvcException.Create(GetOrphStr(SCInvalidParamValue));
  1144.   end;
  1145.   efPositionCaret(False);
  1146. end;
  1147.  
  1148. function TOvcCustomSimpleField.efTransfer(DataPtr : Pointer; TransferFlag : Word) : Word;
  1149.   {-transfer data to/from the entry fields}
  1150. var
  1151.   S : TEditString;
  1152.  
  1153.   procedure TransferString;
  1154.   var
  1155.     I : Integer;
  1156.   begin
  1157.     if TransferFlag = otf_GetData then
  1158.       ShortString(DataPtr^) := StrPas(efEditSt)
  1159.     else begin
  1160.       if ShortString(DataPtr^) = '' then
  1161.         efEditSt[0] := #0
  1162.       else begin
  1163.         StrPLCopy(efEditSt, ShortString(DataPtr^), MaxLength);
  1164.         for I := 0 to Integer(StrLen(efEditSt))-1 do
  1165.           efFixCase(efNthMaskChar(I), efEditSt[I], #255);
  1166.       end;
  1167.     end;
  1168.   end;
  1169.  
  1170.   procedure TransferChar;
  1171.   begin
  1172.     if TransferFlag = otf_GetData then
  1173.       AnsiChar(DataPtr^) := efEditSt[0]
  1174.     else begin
  1175.       efEditSt[0] := AnsiChar(DataPtr^);
  1176.       efEditSt[1] := #0;
  1177.     end;
  1178.   end;
  1179.  
  1180.   procedure TransferBoolean;
  1181.   begin
  1182.     if TransferFlag = otf_GetData then
  1183.       Boolean(DataPtr^) := (UpCaseChar(efEditSt[0]) = IntlSupport.TrueChar)
  1184.     else begin
  1185.       if Boolean(DataPtr^) then
  1186.         efEditSt[0] := IntlSupport.TrueChar
  1187.       else
  1188.         efEditSt[0] := IntlSupport.FalseChar;
  1189.       efEditSt[1] := #0;
  1190.     end;
  1191.   end;
  1192.  
  1193.   procedure TransferYesNo;
  1194.   begin
  1195.     if TransferFlag = otf_GetData then
  1196.       Boolean(DataPtr^) := (UpCaseChar(efEditSt[0]) = IntlSupport.YesChar)
  1197.     else begin
  1198.       if Boolean(DataPtr^) then
  1199.         efEditSt[0] := IntlSupport.YesChar
  1200.       else
  1201.         efEditSt[0] := IntlSupport.NoChar;
  1202.       efEditSt[1] := #0;
  1203.     end;
  1204.   end;
  1205.  
  1206.   procedure TransferLongInt;
  1207.   begin
  1208.     if TransferFlag = otf_GetData then begin
  1209.       if not efStr2Long(efEditSt, LongInt(DataPtr^)) then
  1210.         LongInt(DataPtr^) := 0;
  1211.     end else
  1212.       efLong2Str(efEditSt, LongInt(DataPtr^));
  1213.   end;
  1214.  
  1215.   procedure TransferWord;
  1216.   var
  1217.     L : LongInt;
  1218.   begin
  1219.     if TransferFlag = otf_GetData then begin
  1220.       if efStr2Long(efEditSt, L) then
  1221.         Word(DataPtr^) := Word(L)
  1222.       else
  1223.         Word(DataPtr^) := 0;
  1224.     end else
  1225.       efLong2Str(efEditSt, Word(DataPtr^));
  1226.   end;
  1227.  
  1228.   procedure TransferInteger;
  1229.   var
  1230.     L : LongInt;
  1231.   begin
  1232.     if TransferFlag = otf_GetData then begin
  1233.       if efStr2Long(efEditSt, L) then
  1234.         SmallInt(DataPtr^) := SmallInt(L)
  1235.       else
  1236.         SmallInt(DataPtr^) := 0;
  1237.     end else
  1238.       efLong2Str(efEditSt, SmallInt(DataPtr^));
  1239.   end;
  1240.  
  1241.   procedure TransferByte;
  1242.   var
  1243.     L : LongInt;
  1244.   begin
  1245.     if TransferFlag = otf_GetData then begin
  1246.       if efStr2Long(efEditSt, L) then
  1247.         Byte(DataPtr^) := Byte(L)
  1248.       else
  1249.         Byte(DataPtr^) := 0;
  1250.     end else
  1251.       efLong2Str(efEditSt, Byte(DataPtr^));
  1252.   end;
  1253.  
  1254.   procedure TransferShortInt;
  1255.   var
  1256.     L : LongInt;
  1257.   begin
  1258.     if TransferFlag = otf_GetData then begin
  1259.       if efStr2Long(efEditSt, L) then
  1260.         ShortInt(DataPtr^) := ShortInt(L)
  1261.       else
  1262.         ShortInt(DataPtr^) := 0;
  1263.     end else
  1264.       efLong2Str(efEditSt, ShortInt(DataPtr^));
  1265.   end;
  1266.  
  1267.   procedure TransferReal;
  1268.   label
  1269.     UseExp;
  1270.   var
  1271.     Code : Integer;
  1272.     I    : Cardinal;
  1273.     R    : Real;
  1274.   begin
  1275.     if TransferFlag = otf_GetData then begin
  1276.       StrCopy(S, efEditSt);
  1277.       FixRealPrim(S, IntlSupport.DecimalChar);
  1278.       Val(PAnsiChar(@S[0]), R, Code);
  1279.       if Code <> 0 then
  1280.         R := 0;
  1281.       Real(DataPtr^) := R;
  1282.     end else begin
  1283.       {try to use regular notation}
  1284.       R := Real(DataPtr^);
  1285.       if StrScan(efPicture, pmScientific) <> nil then
  1286.         goto UseExp;
  1287.       Str(R:0:DecimalPlaces, S);
  1288.  
  1289.       {trim trailing 0's if appropriate}
  1290.       if StrScan(S, pmDecimalPt) <> nil  then
  1291.         TrimTrailingZerosPChar(S);
  1292.  
  1293.       {does it fit?}
  1294.       if StrLen(S) > MaxLength then begin
  1295.         {won't fit--use scientific notation}
  1296.   UseExp:
  1297.         if (DecimalPlaces <> 0) and (9+DecimalPlaces < MaxLength) then
  1298.           Str(R:9+DecimalPlaces, S)
  1299.         else
  1300.           Str(R:MaxLength, S);
  1301.         TrimAllSpacesPChar(S);
  1302.         TrimEmbeddedZerosPChar(S);
  1303.       end;
  1304.  
  1305.       {convert decimal point}
  1306.       if StrChPos(S, pmDecimalPt, I) then
  1307.         S[I] := IntlSupport.DecimalChar;
  1308.  
  1309.       StrLCopy(efEditSt, S, MaxLength);
  1310.     end;
  1311.   end;
  1312.  
  1313.   procedure TransferExtended;
  1314.   label
  1315.     UseExp;
  1316.   var
  1317.     Code : Integer;
  1318.     I    : Cardinal;
  1319.     E    : Extended;
  1320.   begin
  1321.     if TransferFlag = otf_GetData then begin
  1322.       StrCopy(S, efEditSt);
  1323.       FixRealPrim(S, IntlSupport.DecimalChar);
  1324.       Val(S, E, Code);
  1325.       if Code <> 0 then
  1326.         E := 0;
  1327.       Extended(DataPtr^) := E;
  1328.     end else begin
  1329.       {try to use regular notation}
  1330.       E := Extended(DataPtr^);
  1331.       if StrScan(efPicture, pmScientific) <> nil then
  1332.         goto UseExp;
  1333.       Str(E:0:DecimalPlaces, S);
  1334.  
  1335.       {trim trailing 0's if appropriate}
  1336.       if StrScan(S, pmDecimalPt) <> nil  then
  1337.         TrimTrailingZerosPChar(S);
  1338.  
  1339.       {does it fit?}
  1340.       if StrLen(S) > MaxLength then begin
  1341.         {won't fit--use scientific notation}
  1342.   UseExp:
  1343.         if (DecimalPlaces <> 0) and (9+DecimalPlaces < MaxLength) then
  1344.           Str(E:9+DecimalPlaces, S)
  1345.         else
  1346.           Str(E:MaxLength, S);
  1347.         TrimAllSpacesPChar(S);
  1348.         TrimEmbeddedZerosPChar(S);
  1349.       end;
  1350.  
  1351.       {convert decimal point}
  1352.       if StrChPos(S, pmDecimalPt, I) then
  1353.         S[I] := IntlSupport.DecimalChar;
  1354.  
  1355.       StrLCopy(efEditSt, S, MaxLength);
  1356.     end;
  1357.   end;
  1358.  
  1359.   procedure TransferDouble;
  1360.   label
  1361.     UseExp;
  1362.   var
  1363.     Code : Integer;
  1364.     I    : Cardinal;
  1365.     D    : Double;
  1366.   begin
  1367.     if TransferFlag = otf_GetData then begin
  1368.       StrCopy(S, efEditSt);
  1369.       FixRealPrim(S, IntlSupport.DecimalChar);
  1370.       Val(PAnsiChar(@S[0]), D, Code);
  1371.       if Code <> 0 then
  1372.         D := 0;
  1373.       Double(DataPtr^) := D;
  1374.     end else begin
  1375.       {try to use regular notation}
  1376.       D := Double(DataPtr^);
  1377.       if StrScan(efPicture, pmScientific) <> nil then
  1378.         goto UseExp;
  1379.       Str(D:0:DecimalPlaces, S);
  1380.  
  1381.       {trim trailing 0's if appropriate}
  1382.       if StrScan(S, pmDecimalPt) <> nil  then
  1383.         TrimTrailingZerosPChar(S);
  1384.  
  1385.       {does it fit?}
  1386.       if StrLen(S) > MaxLength then begin
  1387.         {won't fit--use scientific notation}
  1388.   UseExp:
  1389.         if (DecimalPlaces <> 0) and (9+DecimalPlaces < MaxLength) then
  1390.           Str(D:9+DecimalPlaces, S)
  1391.         else
  1392.           Str(D:MaxLength, S);
  1393.         TrimAllSpacesPChar(S);
  1394.         TrimEmbeddedZerosPChar(S);
  1395.       end;
  1396.  
  1397.       {convert decimal point}
  1398.       if StrChPos(S, pmDecimalPt, I) then
  1399.         S[I] := IntlSupport.DecimalChar;
  1400.  
  1401.       StrLCopy(efEditSt, S, MaxLength);
  1402.     end;
  1403.   end;
  1404.  
  1405.   procedure TransferSingle;
  1406.   label
  1407.     UseExp;
  1408.   var
  1409.     Code : Integer;
  1410.     I    : Cardinal;
  1411.     G    : Single;
  1412.   begin
  1413.     if TransferFlag = otf_GetData then begin
  1414.       StrCopy(S, efEditSt);
  1415.       FixRealPrim(S, IntlSupport.DecimalChar);
  1416.       Val(S, G, Code);
  1417.       if Code <> 0 then
  1418.         G := 0;
  1419.       Single(DataPtr^) := G;
  1420.     end else begin
  1421.       {try to use regular notation}
  1422.       G := Single(DataPtr^);
  1423.       if StrScan(efPicture, pmScientific) <> nil then
  1424.         goto UseExp;
  1425.       Str(G:0:DecimalPlaces, S);
  1426.  
  1427.       {trim trailing 0's if appropriate}
  1428.       if StrScan(S, pmDecimalPt) <> nil  then
  1429.         TrimTrailingZerosPChar(S);
  1430.  
  1431.       {does it fit?}
  1432.       if StrLen(S) > MaxLength then begin
  1433.         {won't fit--use scientific notation}
  1434.   UseExp:
  1435.         if (DecimalPlaces <> 0) and (9+DecimalPlaces < MaxLength) then
  1436.           Str(G:9+DecimalPlaces, S)
  1437.         else
  1438.           Str(G:MaxLength, S);
  1439.         TrimAllSpacesPChar(S);
  1440.         TrimEmbeddedZerosPChar(S);
  1441.       end;
  1442.  
  1443.       {convert decimal point}
  1444.       if StrChPos(S, pmDecimalPt, I) then
  1445.         S[I] := IntlSupport.DecimalChar;
  1446.  
  1447.       StrLCopy(efEditSt, S, MaxLength);
  1448.     end;
  1449.   end;
  1450.  
  1451.   procedure TransferComp;
  1452.     {-transfer data to or from Comp fields}
  1453.   label
  1454.     UseExp;
  1455.   var
  1456.     Code : Integer;
  1457.     C    : Comp;
  1458.   begin
  1459.     if TransferFlag = otf_GetData then begin
  1460.       StrCopy(S, efEditSt);
  1461.       FixRealPrim(S, IntlSupport.DecimalChar);
  1462.       Val(PAnsiChar(@S[0]), C, Code);
  1463.       if Code <> 0 then
  1464.         C := 0;
  1465.       Comp(DataPtr^) := C;
  1466.     end else begin
  1467.       {try to use regular notation}
  1468.       C := Comp(DataPtr^);
  1469.       if StrScan(efPicture, pmScientific) <> nil then
  1470.         goto UseExp;
  1471.       Str(C:0:DecimalPlaces, S);
  1472.  
  1473.       {trim trailing 0's if appropriate}
  1474.       if StrScan(S, pmDecimalPt) <> nil  then
  1475.         TrimTrailingZerosPChar(S);
  1476.  
  1477.       {does it fit?}
  1478.       if StrLen(S) > MaxLength then begin
  1479.         {won't fit--use scientific notation}
  1480.   UseExp:
  1481.         Str(C:MaxLength, S);
  1482.         TrimAllSpacesPChar(S);
  1483.         TrimEmbeddedZerosPChar(S);
  1484.       end;
  1485.       StrLCopy(efEditSt, S, MaxLength);
  1486.     end;
  1487.   end;
  1488.  
  1489. begin  {transfer}
  1490.   if DataPtr = nil then begin
  1491.     Result := 0;
  1492.     Exit;
  1493.   end;
  1494.  
  1495.   case FSimpleDataType of
  1496.     sftString   : TransferString;
  1497.     sftChar     : TransferChar;
  1498.     sftBoolean  : TransferBoolean;
  1499.     sftYesNo    : TransferYesNo;
  1500.     sftLongInt  : TransferLongInt;
  1501.     sftWord     : TransferWord;
  1502.     sftInteger  : TransferInteger;
  1503.     sftByte     : TransferByte;
  1504.     sftShortInt : TransferShortInt;
  1505.     sftReal     : TransferReal;
  1506.     sftExtended : TransferExtended;
  1507.     sftDouble   : TransferDouble;
  1508.     sftSingle   : TransferSingle;
  1509.     sftComp     : TransferComp;
  1510.   else
  1511.     raise EOvcException.Create(GetOrphStr(SCInvalidParamValue));
  1512.   end;
  1513.  
  1514.   Result := inherited efTransfer(DataPtr, TransferFlag);
  1515. end;
  1516.  
  1517. function  TOvcCustomSimpleField.efValidateField : Word;
  1518.   {-validate contents of field; result is error code or 0}
  1519. var
  1520.   S : TEditString;
  1521.  
  1522.   procedure ValidateString;
  1523.   var
  1524.     L : Word;
  1525.   begin
  1526.     if sefGettingValue in sefOptions then
  1527.       Exit;
  1528.  
  1529.     if efoTrimBlanks in Options then
  1530.       if sefHaveFocus in sefOptions then begin
  1531.         L := StrLen(efEditSt);
  1532.         TrimAllSpacesPChar(efEditSt);
  1533.         if StrLen(efEditSt) <> L then
  1534.           Invalidate;
  1535.       end;
  1536.   end;
  1537.  
  1538.   procedure ValidateChar;
  1539.   begin
  1540.     if (efRangeLo.rtChar <> efRangeHi.rtChar) and
  1541.       ((efEditSt[0] < efRangeLo.rtChar) or (efEditSt[0] > efRangeHi.rtChar)) then
  1542.       Result := oeRangeError;
  1543.   end;
  1544.  
  1545.   procedure ValidateBoolean;
  1546.   begin
  1547.     if (UpCaseChar(efEditSt[0]) <> IntlSupport.TrueChar) and
  1548.        (UpCaseChar(efEditSt[0]) <> IntlSupport.FalseChar) then
  1549.       Result := oeRangeError;
  1550.   end;
  1551.  
  1552.   procedure ValidateYesNo;
  1553.   begin
  1554.     if (UpCaseChar(efEditSt[0]) <> IntlSupport.YesChar) and
  1555.        (UpCaseChar(efEditSt[0]) <> IntlSupport.NoChar) then
  1556.       Result := oeRangeError;
  1557.   end;
  1558.  
  1559.   procedure ValidateLongInt;
  1560.   var
  1561.     L : LongInt;
  1562.   begin
  1563.     if not efStr2Long(efEditSt, L) then
  1564.       Result := oeInvalidNumber
  1565.     else if (L < efRangeLo.rtLong) or (L > efRangeHi.rtLong) then
  1566.       Result := oeRangeError
  1567.     else begin
  1568.       if sefHaveFocus in sefOptions then
  1569.         if not (sefGettingValue in sefOptions) then begin
  1570.           efTransfer(@L, otf_SetData);
  1571.           Invalidate;
  1572.         end;
  1573.     end;
  1574.   end;
  1575.  
  1576.   procedure ValidateWord;
  1577.   var
  1578.     L : LongInt;
  1579.   begin
  1580.     if not efStr2Long(efEditSt, L) then
  1581.       Result := oeInvalidNumber
  1582.     else if (L < efRangeLo.rtLong) or (L > efRangeHi.rtLong) then
  1583.       Result := oeRangeError
  1584.     else begin
  1585.       if sefHaveFocus in sefOptions then
  1586.         if not (sefGettingValue in sefOptions) then begin
  1587.           efTransfer(@L, otf_SetData);
  1588.           Invalidate;
  1589.         end;
  1590.     end;
  1591.   end;
  1592.  
  1593.   procedure ValidateInteger;
  1594.   var
  1595.     L : LongInt;
  1596.     I : Integer;
  1597.   begin
  1598.     if not efStr2Long(efEditSt, L) then
  1599.       Result := oeInvalidNumber
  1600.     else if (L < efRangeLo.rtLong) or (L > efRangeHi.rtLong) then
  1601.       Result := oeRangeError
  1602.     else begin
  1603.       if sefHaveFocus in sefOptions then
  1604.         if not (sefGettingValue in sefOptions) then begin
  1605.           I := L;
  1606.           efTransfer(@I, otf_SetData);
  1607.           Invalidate;
  1608.         end;
  1609.     end;
  1610.   end;
  1611.  
  1612.   procedure ValidateByte;
  1613.   var
  1614.     L : LongInt;
  1615.     B : Byte;
  1616.   begin
  1617.     if not efStr2Long(efEditSt, L) then
  1618.       Result := oeInvalidNumber
  1619.     else if (L < efRangeLo.rtLong) or (L > efRangeHi.rtLong) then
  1620.       Result := oeRangeError
  1621.     else begin
  1622.       if sefHaveFocus in sefOptions then
  1623.         if not (sefGettingValue in sefOptions) then begin
  1624.           B := L;
  1625.           efTransfer(@B, otf_SetData);
  1626.           Invalidate;
  1627.         end;
  1628.     end;
  1629.   end;
  1630.  
  1631.   procedure ValidateShortInt;
  1632.   var
  1633.     L  : LongInt;
  1634.     Si : ShortInt;
  1635.   begin
  1636.     if not efStr2Long(efEditSt, L) then
  1637.       Result := oeInvalidNumber
  1638.     else if (L < efRangeLo.rtLong) or (L > efRangeHi.rtLong) then
  1639.       Result := oeRangeError
  1640.     else begin
  1641.       if sefHaveFocus in sefOptions then
  1642.         if not (sefGettingValue in sefOptions) then begin
  1643.           Si := L;
  1644.           efTransfer(@Si, otf_SetData);
  1645.           Invalidate;
  1646.         end;
  1647.     end;
  1648.   end;
  1649.  
  1650.   procedure ValidateReal;
  1651.   var
  1652.     R    : Real;
  1653.     Code : Integer;
  1654.   begin
  1655.     {convert efEditSt to a real}
  1656.     StrLCopy(S, efEditSt, 80);
  1657.     FixRealPrim(S, IntlSupport.DecimalChar);
  1658.     Val(S, R, Code);
  1659.  
  1660.     {format OK?}
  1661.     if Code <> 0 then
  1662.       Result := oeInvalidNumber
  1663.     else if (R < efRangeLo.rtReal) or (R > efRangeHi.rtReal) then
  1664.       Result := oeRangeError
  1665.     else begin
  1666.       if sefHaveFocus in sefOptions then
  1667.         if not (sefGettingValue in sefOptions) then begin
  1668.           efTransfer(@R, otf_SetData);
  1669.           Invalidate;
  1670.         end;
  1671.     end;
  1672.   end;
  1673.  
  1674.   procedure ValidateExtended;
  1675.   var
  1676.     E    : Extended;
  1677.     Code : Integer;
  1678.   begin
  1679.     {convert efEditSt to an extended}
  1680.     StrLCopy(S, efEditSt, 80);
  1681.     FixRealPrim(S, IntlSupport.DecimalChar);
  1682.     Val(S, E, Code);
  1683.     if Code <> 0 then
  1684.       Result := oeInvalidNumber
  1685.     else if (E < efRangeLo.rtExt) or (E > efRangeHi.rtExt) then
  1686.       Result := oeRangeError
  1687.     else begin
  1688.       if sefHaveFocus in sefOptions then
  1689.         if not (sefGettingValue in sefOptions) then begin
  1690.           efTransfer(@E, otf_SetData);
  1691.           Invalidate;
  1692.         end;
  1693.     end;
  1694.   end;
  1695.  
  1696.   procedure ValidateDouble;
  1697.   var
  1698.     E    : Extended;
  1699.     D    : Double;
  1700.     Code : Integer;
  1701.   begin
  1702.     {convert efEditSt to an extended}
  1703.     StrLCopy(S, efEditSt, 80);
  1704.     FixRealPrim(S, IntlSupport.DecimalChar);
  1705.     Val(S, E, Code);
  1706.     if Code <> 0 then
  1707.       Result := oeInvalidNumber
  1708.     else if (E < efRangeLo.rtExt) or (E > efRangeHi.rtExt) then
  1709.       Result := oeRangeError
  1710.     else begin
  1711.       if sefHaveFocus in sefOptions then
  1712.         if not (sefGettingValue in sefOptions) then begin
  1713.           D := E;
  1714.           efTransfer(@D, otf_SetData);
  1715.           Invalidate;
  1716.         end;
  1717.     end;
  1718.   end;
  1719.  
  1720.   procedure ValidateSingle;
  1721.   var
  1722.     E    : Extended;
  1723.     Si   : Single;
  1724.     Code : Integer;
  1725.   begin
  1726.     {convert efEditSt to an extended}
  1727.     StrLCopy(S, efEditSt, 80);
  1728.     FixRealPrim(S, IntlSupport.DecimalChar);
  1729.     Val(S, E, Code);
  1730.     if Code <> 0 then
  1731.       Result := oeInvalidNumber
  1732.     else if (E < efRangeLo.rtExt) or (E > efRangeHi.rtExt) then
  1733.       Result := oeRangeError
  1734.     else begin
  1735.       if sefHaveFocus in sefOptions then
  1736.         if not (sefGettingValue in sefOptions) then begin
  1737.           Si := E;
  1738.           efTransfer(@Si, otf_SetData);
  1739.           Invalidate;
  1740.         end;
  1741.     end;
  1742.   end;
  1743.  
  1744.   procedure ValidateComp;
  1745.   var
  1746.     E    : Extended;
  1747.     C    : Comp;
  1748.     Code : Integer;
  1749.   begin
  1750.     {convert efEditSt to an extended}
  1751.     StrLCopy(S, efEditSt, 80);
  1752.     FixRealPrim(S, IntlSupport.DecimalChar);
  1753.     Val(S, C, Code);
  1754.     E := C;
  1755.     if Code <> 0 then
  1756.       Result := oeInvalidNumber
  1757.     else if (E < efRangeLo.rtExt) or (E > efRangeHi.rtExt) then
  1758.       Result := oeRangeError
  1759.     else begin
  1760.       if sefHaveFocus in sefOptions then
  1761.         if not (sefGettingValue in sefOptions) then begin
  1762.           efTransfer(@C, otf_SetData);
  1763.           Invalidate;
  1764.         end;
  1765.     end;
  1766.   end;
  1767.  
  1768. begin
  1769.   Result := 0;
  1770.   case FSimpleDataType of
  1771.     sftString   : ValidateString;
  1772.     sftChar     : ValidateChar;
  1773.     sftBoolean  : ValidateBoolean;
  1774.     sftYesNo    : ValidateYesNo;
  1775.     sftLongInt  : ValidateLongInt;
  1776.     sftWord     : ValidateWord;
  1777.     sftInteger  : ValidateInteger;
  1778.     sftByte     : ValidateByte;
  1779.     sftShortInt : ValidateShortInt;
  1780.     sftReal     : ValidateReal;
  1781.     sftExtended : ValidateExtended;
  1782.     sftDouble   : ValidateDouble;
  1783.     sftSingle   : ValidateSingle;
  1784.     sftComp     : ValidateComp;
  1785.   end;
  1786.  
  1787.   if not (sefUserValidating in sefOptions) then begin
  1788.     {user may retrieve data from field. flag that we are doing}
  1789.     {user validation to avoid calling this routine recursively}
  1790.     Include(sefOptions, sefUserValidating);
  1791.     DoOnUserValidation(Result);
  1792.     Exclude(sefOptions, sefUserValidating);
  1793.   end;
  1794. end;
  1795.  
  1796. procedure TOvcCustomSimpleField.sfSetDataType(Value : TSimpleDataType);
  1797.   {-set the data type for this field}
  1798. begin
  1799.   if FSimpleDataType <> Value then begin
  1800.     FSimpleDataType := Value;
  1801.     efDataType := sfGetDataType(FSimpleDataType);
  1802.     Options := Options + [efoCaretToEnd];
  1803.     efSetDefaultRange(efDataType);
  1804.  
  1805.     {set defaults for this field type}
  1806.     sfResetFieldProperties(FSimpleDataType);
  1807.     if HandleAllocated then begin
  1808.       {don't save data through create window}
  1809.       efSaveData := False;
  1810.       RecreateWnd;
  1811.     end;
  1812.   end;
  1813. end;
  1814.  
  1815. procedure TOvcCustomSimpleField.sfSetPictureMask(Value: AnsiChar);
  1816.   {-set the picture mask}
  1817. var
  1818.   Buf : array[0..1] of AnsiChar;
  1819. begin
  1820.   if FPictureMask <> Value then begin
  1821.     if Value in SimplePictureChars then begin
  1822.       FPictureMask := Value;
  1823.       if csDesigning in ComponentState then begin
  1824.         efPicture[0] := Value;
  1825.         efPicture[1] := #0;
  1826.         Repaint;
  1827.       end else begin
  1828.         Buf[0] := Value;
  1829.         Buf[1] := #0;
  1830.         efChangeMask(Buf);
  1831.         RecreateWnd;
  1832.       end;
  1833.     end else
  1834.       raise EInvalidPictureMask.Create(Value);
  1835.   end;
  1836. end;
  1837.  
  1838. function TOvcCustomSimpleField.sfGetDataType(Value : TSimpleDataType) : Byte;
  1839.   {-return a Byte value representing the type of this field}
  1840. begin
  1841.   case Value of
  1842.     sftString    : Result := fidSimpleString;
  1843.     sftChar      : Result := fidSimpleChar;
  1844.     sftBoolean   : Result := fidSimpleBoolean;
  1845.     sftYesNo     : Result := fidSimpleYesNo;
  1846.     sftLongInt   : Result := fidSimpleLongInt;
  1847.     sftWord      : Result := fidSimpleWord;
  1848.     sftInteger   : Result := fidSimpleInteger;
  1849.     sftByte      : Result := fidSimpleByte;
  1850.     sftShortInt  : Result := fidSimpleShortInt;
  1851.     sftReal      : Result := fidSimpleReal;
  1852.     sftExtended  : Result := fidSimpleExtended;
  1853.     sftDouble    : Result := fidSimpleDouble;
  1854.     sftSingle    : Result := fidSimpleSingle;
  1855.     sftComp      : Result := fidSimpleComp;
  1856.   else
  1857.     raise EOvcException.Create(GetOrphStr(SCInvalidParamValue));
  1858.   end;
  1859. end;
  1860.  
  1861. procedure TOvcCustomSimpleField.sfResetFieldProperties(FT : TSimpleDataType);
  1862.   {-reset field properties based on current setings}
  1863.  
  1864.   procedure Update(Len: Word; Mask: AnsiChar);
  1865.   begin
  1866.     MaxLength := Len;
  1867.     FPictureMask := Mask;
  1868.     efPicture[0] := Mask;
  1869.     efPicture[1] := #0;
  1870.     DecimalPlaces := 0;
  1871.   end;
  1872.  
  1873. begin
  1874.   case FT of
  1875.     sftString    : Update(15, pmAnyChar);
  1876.     sftBoolean   : Update(1, pmTrueFalse);
  1877.     sftYesNo     : Update(1, pmYesNo);
  1878.     sftChar      : Update(1, pmAnyChar);
  1879.     sftLongInt   : Update(8, pmWhole);
  1880.     sftWord      : Update(5, pmPositive);
  1881.     sftInteger   : Update(5, pmWhole);
  1882.     sftByte      : Update(3, pmPositive);
  1883.     sftShortInt  : Update(4, pmWhole);
  1884.     sftReal      : Update(14, pmDecimal);
  1885.     sftExtended  : Update(14, pmDecimal);
  1886.     sftDouble    : Update(14, pmDecimal);
  1887.     sftSingle    : Update(14, pmDecimal);
  1888.     sftComp      : Update(14, pmWhole);
  1889.   else
  1890.     raise EOvcException.Create(GetOrphStr(SCInvalidParamValue));
  1891.   end;
  1892. end;
  1893.  
  1894. procedure TOvcCustomSimpleField.sfSetDefaultRanges;
  1895.   {-set default range values based on the field type}
  1896. begin
  1897.   case FSimpleDataType of
  1898.     sftChar, sftBoolean, sftYesNo :
  1899.       if efRangeLo.rtChar = efRangeHi.rtChar then
  1900.         efSetDefaultRange(efDataType);
  1901.     sftLongInt, sftWord, sftInteger, sftByte, sftShortInt :
  1902.       if efRangeLo.rtLong = efRangeHi.rtLong then
  1903.         efSetDefaultRange(efDataType);
  1904.     sftReal :
  1905.       if efRangeLo.rtReal = efRangeHi.rtReal then
  1906.         efSetDefaultRange(efDataType);
  1907.     sftExtended, sftDouble, sftSingle, sftComp :
  1908.       if efRangeLo.rtExt = efRangeHi.rtExt then
  1909.         efSetDefaultRange(efDataType);
  1910.   else
  1911.     efSetDefaultRange(efDataType);
  1912.   end;
  1913. end;
  1914.  
  1915.  
  1916. end.
  1917.